package com.googlecode.dgwt.client.dojo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.googlecode.dgwt.client.dojo.callback.BooleanCallback;


/**
 * @author	Wellington Tadeu dos Santos
 * @since	DGWT v0.01
 */
public class NodeList<N extends Node> extends ArrayList<N> {

    private static final long serialVersionUID = 1L;
    
    
    public NodeList(){
        super();
    }
    
    
    public NodeList(int length){
        super(length);
    }
    
    
    public NodeList(Node[] nodes){
        super(nodes.length);
        for (Node node : nodes){
            add(node.<N>cast());
        }
    }
    
    
    @SuppressWarnings("unchecked")
    public NodeList(Collection<? extends Node> source){
        super((Collection)source);
    }
    

    @SuppressWarnings("unchecked")
    public <T extends Node> NodeList<T> cast(){
        return (NodeList) this;
    }


    public NodeList<N> filter(BooleanCallback<N> doFilter){
        Iterator<N> iterator = this.iterator();
        
        while (iterator.hasNext()){
            if (!doFilter.callback(iterator.next())){
                iterator.remove();
            }
        }
        
        return this;
    }

    
    public <T extends Node> NodeList<T> query(String query){
        NodeList<T> nodeList = new NodeList<T>(size());
        
        for (Node node : this){
            Dojo.query(query, node, nodeList);
        }
        
        return nodeList;
    }
    
    
    /**
     * Accesses styles on a node
     * 
     * @param node
     *            node to set style for
     * 
     * @param name
     *            the style property to set in DOM-accessor format
     *            ("borderWidth", not "border-width") or an object with
     *            key/value pairs suitable for setting each property
     * 
     * @param value
     *            sets value on the node for style, handling cross-browser
     *            concerns
     */
    public void setStyle(String name, String value) {
        for (Node node : this){
            Dojo.setStyle(node, name, value);
        }
    }


    /**
     * Adds the specified classes to the end of the class list on the passed node.
     * Will not re-apply duplicate classes, except in edge
     * cases when adding multiple classes at once.
     * 
     * @param node DOM node
     * @param className CSS class name
     */
    public void addClass(String value) {
        for (Node node : this){
            if (Element.is(node)) {
                Dojo.addClass(node.<Element>cast(), value);
            }
        }
    }


}
